package com.ftpserver;

import java.io.File;
import java.io.FileInputStream;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class NIOFileSendClientSocketDemo {
    public static void main(String[] args) throws Exception {
        SocketChannel socketChanel = SocketChannel.open();
        socketChanel.configureBlocking(false);
        socketChanel.connect(new InetSocketAddress("localhost",2345));

        Selector selector = Selector.open();
        long size =0;
        long fileLength = 0;

        //注册
        socketChanel.register(selector, SelectionKey.OP_CONNECT);
        boolean base = true;
        FileChannel fileChannel=null;
        ByteBuffer bb = ByteBuffer.allocateDirect(4096*10);
        ByteBuffer byteBuffer = ByteBuffer.allocate(4);
        FileInputStream fis = null;
        while(true){
            selector.select();
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectionKeys.iterator();

            while (iterator.hasNext()){
                SelectionKey key = iterator.next();
                iterator.remove();
                if(key.isConnectable()){
                    SocketChannel channel = (SocketChannel) key.channel();
                    channel.finishConnect();
                    channel.register(selector,SelectionKey.OP_WRITE);
                }else if(key.isWritable()){
                    if(base) {
                        SocketChannel channel = (SocketChannel) key.channel();
                        File file = new File("D:\\云吞下载\\CentOS-8.5.2111-x86_64-dvd1.1.iso");
                        fis =
                                new FileInputStream(file);
                        fileChannel = fis.getChannel();
                        String fileNmae = file.getName();
                        byte[] gbks = fileNmae.getBytes("GBK");
                        bb.putInt(gbks.length);
                        bb.flip();
                        channel.write(bb);
                        bb.clear();
                        bb.put(gbks);
                        bb.flip();
                        channel.write(bb);
                        bb.clear();
                        bb.putLong(file.length());
                        fileLength=file.length();
                        bb.flip();
                        channel.write(bb);
                        bb.clear();
                        channel.register(selector, SelectionKey.OP_READ);
                        base=false;
                    }else {
                        /**
                         * 相当于等待下次写
                         */
                         int tmplen = 0;
                        SocketChannel channel = (SocketChannel) key.channel();
                        System.out.println("开始时间" + System.currentTimeMillis());
                        if ((tmplen = fileChannel.read(bb)) != -1) {
                            bb.flip();
                            channel.write(bb);
                            bb.clear();
                            size += tmplen;
                            System.out.println("总的发送大小:"+fileLength+",本次发送：" + tmplen + ",已发送" + size);

                        }
                        System.out.println("发送完毕");
                        System.out.println("结束时间" + System.currentTimeMillis());
                        channel.register(selector, SelectionKey.OP_READ);
                    }
                }else if(key.isReadable()){
                    SocketChannel channel = (SocketChannel) key.channel();
                    byteBuffer.clear();
                    while( (channel.read(byteBuffer))!=-1){
                        byteBuffer.flip();
                        int comm= byteBuffer.getInt();
                        //继续写
                        byteBuffer.clear();
                        if(1==comm){
                            channel.register(selector, SelectionKey.OP_WRITE);
                            System.out.println("收到继续写，继续写");
                        }else if(2==comm){
                            System.out.println("收到关闭");
                            fileChannel.close();
                            if(fis!=null){
                                fis.close();
                            }
                            System.exit(0);

                        }
                        break;
                    }

                }


            }


        }

    }
}
